

print("_G == _ENV", _G == _ENV) -- true


a = 10;
local a = 11;
print("Local a=", a) -- 11
print("Global a=", _ENV.a) -- 10

print("-----------do end------------------")
do
    local env = {};
    setmetatable(env, {__index = _G});
    local _ENV = env;
    b = 10;
    print("b=", b) -- 10
end
print("b=", b) -- 10


print("-----------load------------------")
local source = [[
    c = 10;
    print("inside c=", c)
    return c;
]]

do
    print("----load 1")
    local env = {print=print};
    local func = load(source, "env.lua", "t", env);
    print("outside func=", func())
    print("outside c=", c)
    print("outside env.c=", env.c)
    local name, upvalueEnv = debug.getupvalue(func, 1)
    print("outside upvalueEnv.c=",upvalueEnv.c)
    print("upvalueEnv == env", upvalueEnv == env)
end

do
    print("----load 2")
    print("global ENV:", _ENV)
    local oldENV = _ENV;
    local _ENV = {print=print, load=load, debug=debug}
    local func = load(source); -- 没有指定环境，会创建一个新的变量，并赋值_G，而不是使用local _ENV
    print("outside func=", func())
    print("outside c=", c)
    print("outside _ENV.c=", _ENV.c)
    local name, upvalueEnv = debug.getupvalue(func, 1)
    print("outside upvalueEnv.c=",upvalueEnv.c)
    print("upvalueEnv == env", upvalueEnv == _ENV)
    print("upvalueEnv == oldENV", upvalueEnv == oldENV)

    print("--after debug.setupvalue, _ENV:", _ENV)
    debug.setupvalue(func, 1, _ENV)
    print("outside func=", func())
    print("outside c=", c)
    print("outside _ENV.c=", _ENV.c)
end
print("global ENV:", _ENV)

print("\n---------------upvalue--------------")
do
    local function fun()
        local a = 10;
        return function()
            print("a=", a)
            a = a + 1
        end
    end

    local f = fun();
    local i = 1; 
    while true do
        local name, value = debug.getupvalue(f, i)
        if name == nil then
            break
        end
        print("upvalue name=", name, " value=", value)
        i = i + 1
    end
end

print("---------------upvalueEnv--------------")
do
    print("global ENV:", _ENV)
    local oldENV = _ENV;
    local _ENV = {print=print}
    print("_ENV:" , _ENV)
    local function func()
        print("_ENV:" , _ENV)
        print("inside func")
        print("inside d=", d)
        d = 20
    end

    print("before debug.setupvalue")
    func()

    local newFuncEnv = {print=print, d = 10}
    print("newFuncEnv:", newFuncEnv)

    _ENV = oldENV
    debug.setupvalue(func, 1, newFuncEnv) -- 会修改 _ENV 的值
    print("_ENV:", _ENV)
    print("after debug.setupvalue")
    func()
    print("outside d=", d)
end
print("global ENV:", _ENV)